package mbspliter

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
)

const (
	ONE   = "one"
	TWO   = "two"
	THREE = "three"
	FOUR  = "four"
)

func Split(path string) error {
	f, err := os.Open(path)
	if err != nil {
		return err
	}
	defer f.Close()

	err = os.Mkdir("output", 0666)
	if err != nil {
		fmt.Println(err.Error())
	}

	f1, f2, f3, f4, err := getFiles(path)
	if err != nil {
		return err
	}
	defer func() {
		f1.Close()
		f2.Close()
		f3.Close()
		f4.Close()
	}()

	rd := bufio.NewReader(f)
	w1 := bufio.NewWriter(f1)
	w2 := bufio.NewWriter(f2)
	w3 := bufio.NewWriter(f3)
	w4 := bufio.NewWriter(f4)

	for {
		line, _, err := rd.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			return err
		}

		if isSkip(line) {
			continue
		}

		duo, err := isDuo(line)
		if err != nil {
			return err
		}

		if duo {
			// 多多
			lineStr := string(line)
			sLine := strings.Split(lineStr, "	")
			len := len(sLine[0])

			newStr := lineStr + "\n"

			len /= 3
			if len == 1 {
				// 单字
				w1.WriteString(newStr)
			} else if len == 2 {
				// 二字词
				w2.WriteString(newStr)
			} else if len == 3 {
				// 三字词
				w3.WriteString(newStr)
			} else {
				// 四字以上词
				w4.WriteString(newStr)
			}
		} else {
			// 极点
			lineStr := string(line)
			sLine := strings.Split(lineStr, " ")
			len := len(sLine[1])

			newStr := lineStr + "\n"

			len /= 3
			if len == 1 {
				// 单字
				w1.WriteString(newStr)
			} else if len == 2 {
				// 二字词
				w2.WriteString(newStr)
			} else if len == 3 {
				// 三字词
				w3.WriteString(newStr)
			} else {
				// 四字以上词
				w4.WriteString(newStr)
			}
		}
	}

	w1.Flush()
	w2.Flush()
	w3.Flush()
	w4.Flush()

	fmt.Println("处理完毕")

	return nil
}

func getFiles(path string) (*os.File, *os.File, *os.File, *os.File, error) {
	onePath := "output/one.txt"
	twoPath := "output/two.txt"
	threePath := "output/three.txt"
	fourPath := "output/four.txt"

	f1, err := os.Create(onePath)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	f2, err := os.Create(twoPath)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	f3, err := os.Create(threePath)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	f4, err := os.Create(fourPath)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	return f1, f2, f3, f4, nil
}

// checkConsistency 检查格式一致性
// 不允许文件内同时存在多多和极点两种格式
// @return bool：是否是多多格式
// 				- true：是多多
func checkForm(mb string) (bool, error) {
	f, err := os.Open(mb)
	if err != nil {
		return false, err
	}
	defer f.Close()

	rd := bufio.NewReader(f)

	// 按行遍历
	// 找到第一行非注释
	// 是否是多多格式
	var fstForm bool
	for {
		line, _, err := rd.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			return false, err
		}

		if isSkip(line) {
			continue
		}

		form, err := isDuo(line)
		if err != nil {
			return false, err
		}

		fstForm = form
		break
	}

	// 继续按行遍历，若发现与第一行格式不符的，报错
	for {
		line, _, err := rd.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			return false, err
		}

		lineForm, err := isDuo(line)
		if err != nil {
			return false, err
		}
		if fstForm != lineForm {
			return false, fmt.Errorf("检查到文件内格式不一致，请检查是否文件内所有行都为多多或极点格式！")
		}
	}

	return fstForm, nil
}

// isSkip 判断本行是否是可跳过的字符
func isSkip(line []byte) bool {
	if line[0] == '#' {
		return true
	} else if len(line) == 0 {
		return true
	}
	for ind := range line {
		if line[ind] != ' ' && line[ind] != '	' {
			return false
		}
	}
	return true
}

// isDuo 判断一行是否是多多格式的
// @param line: 读取的一行
//
// @return bool：是否是多多格式
//				- true：多多格式
//				- false：极点格式
// @return error：错误
func isDuo(line []byte) (bool, error) {
	str := string(line)

	if strings.Contains(str, "	") {
		// 可能是多多
		s := strings.Split(str, "	")
		if len(s) != 2 {
			fmt.Println("%v", str)
			return false, fmt.Errorf("行内格式不正确！")
		}
		return true, nil
	} else if strings.Contains(str, " ") {
		// 可能是极点
		s := strings.Split(str, " ")
		if len(s) != 2 {
			fmt.Println("%v", str)
			return false, fmt.Errorf("行内格式不正确！")
		}
		return false, nil
	}

	return false, fmt.Errorf("行内格式不正确！")
}
